package Java8实战._3_Stream_用流收集数据._2_归约和汇总;


import Java8实战._3_Stream_用流收集数据.Dish;

import java.util.*;
import java.util.stream.Collectors;


public class _2_汇总 {

    public static void main(String[] args) {
        List<Dish> menu = Arrays.asList(
                new Dish("pork",false,800, Dish.Type.MEAT),
                new Dish("beef",false,700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH)
        );


        /**
         * 求和
         */
        int sum = 0;
        sum = menu.stream()
                .collect(Collectors.summingInt(Dish::getCalories));
        System.out.println("总热量1：" + sum);

        sum = menu.stream()
                .map(Dish::getCalories)
                .reduce(0, (a,b) -> a + b);
        System.out.println("总热量2：" + sum);

        sum = menu.stream()
                .map(Dish::getCalories)
                .reduce(Integer::sum)
                .get();//get()可以代替.ifPresent(a -> System.out.println("总热量2：" + a))
        System.out.println("总热量3：" + sum);

        sum = menu.stream()
                .mapToInt(Dish::getCalories)
                .sum();
        System.out.println("总热量4：" + sum);

        sum = menu.stream()
                .collect(Collectors.reducing(0,Dish::getCalories,(i, j) -> i + j));
        System.out.println("总热量5：" + sum);

        sum = menu.stream()
                .collect(Collectors.reducing(0,Dish::getCalories,Integer::sum));
        System.out.println("总热量6：" + sum);

        System.out.println("\n=================================\n");

        /**
         * 求平均值
         */
        double avg = 0d;
        avg = menu.stream()
                .collect(Collectors.averagingInt(Dish::getCalories));
        System.out.println("平均值1：" + avg);

        avg = menu.stream()
                .mapToInt(Dish::getCalories)
                .average()
                .getAsDouble();
        System.out.println("平均值2：" + avg);

        System.out.println("\n=================================\n");

        /**
         * 最大值
         */
        int max;
        menu.stream()
                .collect(Collectors.maxBy(Comparator.comparing(Dish::getCalories)))
                .ifPresent(dish -> System.out.println("最大值1：" + dish.getCalories()));

        menu.stream()
                .sorted(Comparator.comparing(Dish::getCalories).reversed())
                .limit(1)
                .forEach(dish -> System.out.println("最大值2：" + dish.getCalories()));

        menu.stream()
                .max(Comparator.comparing(Dish::getCalories))
                .ifPresent(dish -> System.out.println("最大值3：" + dish.getCalories()));

        menu.stream()
                .collect(Collectors.reducing((d1,d2) -> d1.getCalories() >= d2.getCalories() ? d1 : d2))
                .ifPresent(dish -> System.out.println("最大值4：" + dish.getCalories()));


        System.out.println("\n=================================\n");

        /**
         * 最小值
         */
        int min;
        menu.stream()
                .collect(Collectors.minBy(Comparator.comparing(Dish::getCalories)))
                .ifPresent(dish -> System.out.println("最小值1：" + dish.getCalories()));

        menu.stream()
                .sorted(Comparator.comparing(Dish::getCalories))
                .limit(1)
                .forEach(dish -> System.out.println("最小值2：" + dish.getCalories()));

        menu.stream()
                .min(Comparator.comparing(Dish::getCalories))
                .ifPresent(dish -> System.out.println("最小值3：" + dish.getCalories()));

        System.out.println("\n=================================\n");

        /**
         * 一次获取
         */
        IntSummaryStatistics collect = menu.stream()
                .collect(Collectors.summarizingInt(Dish::getCalories));

        System.out.println("最大值：" + collect.getMax());
        System.out.println("最小值：" + collect.getMin());
        System.out.println("平均值：" + collect.getAverage());
        System.out.println("求和：" + collect.getSum());
        System.out.println("个数：" + collect.getCount());


    }
}
